#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const request = require('request-client');
const { createLogger, transports, format } = require('winston');
const querystring = require('node:querystring');
const iconv = require('iconv-lite');

const scriptPath = path.dirname(__filename);

const loadCookieFromConfig = () => {
	const content = fs.readFileSync(`${scriptPath}/cookie.json`, 'utf-8');
	return JSON.parse(content).baidu_cookie;
};

class TiebaSigner {
	constructor() {
		this.headers = {
			'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0',
			'Cookie': loadCookieFromConfig()
		};
		this.logger = createLogger({
			level: 'info',
			format: format.combine(
				format.timestamp(),
				format.printf(({ timestamp, level, message }) => `${timestamp} ${level}: ${message}`)
			),
			transports: [
				new transports.File({ filename: 'run.log', maxsize: 10 * 1024 * 1024, maxFiles: 10, options: { encoding: 'utf-8' } }),
				new transports.Console()
			]
		});
	}

	consoleLog(message) {
		this.logger.info(message);
		console.log(message);
	}

	async fetch(url, callback) {
		let prm = {};
		if (typeof url === 'string') {
			prm = { url }
		} else { // object
			prm = url
		}
		prm.headers = this.headers
		return new Promise((resolve, reject) => {
			request(prm, (err, res, body) => {
				if (err) {
					console.warn(`Error fetching URL: ${prm.url}, ${err.message}`);
					reject(err);
				} else {
					if (typeof callback === 'function') {
						callback(err, res, body);
					}
					resolve(body);
				}
			});
		});
	}

	async signAllTheBa() {
		console.log("开始获取账号关注的贴吧列表");
		const url = "https://tieba.baidu.com/f/like/mylike";
		let pageNum;
		try {
			const htmlStr = await this.fetch(url);
			const pnList = htmlStr.match(/pn=(\d+)/g).map(pn => pn.match(/\d+/)[0]);
			pageNum = pnList[pnList.length - 1];
		} catch (error) {
			console.log(error);
			console.warn("cookie为空或者已过期, 请在cookie.json文件中填写正确的cookie后重试");
			return;
		}
		console.log(`列表获取成功，总共${pageNum}页`);

		let n = 0;
		const pageUrl = `https://tieba.baidu.com/f/like/mylike?&pn=2`;
		// for (let i = 1; i <= pageNum; i++) {
		// 	const pageUrl = `https://tieba.baidu.com/f/like/mylike?&pn=${i}`; 
		this.fetch(pageUrl, (err, res, body) => { //每个列表页的操作
			if (err) {
				console.warn(`Error fetching URL: ${prm.url}, ${err.message}`);
			} else {
				const matches = body.match(/<span onclick[^>]+balvname="([^"]+)" tbs="(\w+)"/g);

				for (const one of matches) {
					const [, name, tbs] = one.match(/balvname="([^"]+)" tbs="(\w+)"/);
					const unescapedName = querystring.unescape(name);

					const utf8Name = iconv.decode(unescapedName, 'utf8');
					console.log("utf8Name:::::::::::", utf8Name, tbs);
					// this.singleSign(name, tbs);
					n++;
				}
			}
		});
		// }

		console.log(`执行完毕，共执行签到操作${n}个`);
	}
	// 单个贴吧签到
	async singleSign(kw, tbs) {
	
		const signUrl = "https://tieba.baidu.com/sign/add";
		const data = new URLSearchParams({
			'ie': 'utf-8',
			'kw': kw,
			'tbs': tbs
		});

		await request({
			url: signUrl,
			method: 'POST',
			headers: this.headers,
			body: data.toString()
		}, (err, res, body) => {

			if (err) {
				console.error(`Error signing for ${kw}: ${err.message}`);
			} else {
				try {
					const result = JSON.parse(body);
					if (result.no === 0) {
						const rank = result.data.finfo.current_rank_info.sign_count;
						const num = result.data.uinfo.total_sign_num;
						logger.info(`${kw}吧 签到成功✔, 签到排名：${rank}, 已签到${num}天`);
					} else {
						console.warn(`Failed to sign for ${kw}: ${result.error}`);
					}
				} catch (parseError) {
					console.error(`Error parsing response for ${kw}: ${parseError.message}`);
					console.log(`Raw response: ${body}`);
				}
			}
		});
	}
}

const signer = new TiebaSigner();
signer.signAllTheBa();